<?php
namespace App\Http\Controllers\Api\Hlgc;

use App\Http\Controllers\Controller;
use App\User;
use App\UserCoinLog;
use App\GameZghpt;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Jobs\SendWechatMessage;

/**
 * 欢乐攻城
 *
 * @author  Kay
 * @version 1.0.0
 */
class HlgcController extends Controller {

    const bussiness_id  = 6;        // 欢乐攻城
    const threshold_xyb = -500;    // 止损阀值

    protected $wechat;

    //奖励层级
    private $reward_count = 2;

    protected $config = [
        // 军队类型
        'army_types' => [
            1 => '矛兵',
            2 => '盾兵',
            3 => '弓兵',
        ],
        // 国家类型
        'nation_types' => [
            1 => [
                'label' => '魏',
                'peilv' => [
                    1 => ['id' => 1, 'name' => '赢', 'rate' => 35],
                    2 => ['id' => 2, 'name' => '输', 'rate' => 65],
                    3 => ['id' => 3, 'name' => '平', 'rate' => 25],
                ],
            ],
            2 => [
                'label' => '吴',
                'peilv' => [
                    1 => ['id' => 1, 'name' => '赢', 'rate' => 35],
                    2 => ['id' => 2, 'name' => '输', 'rate' => 65],
                    3 => ['id' => 3, 'name' => '平', 'rate' => 25],
                ],
            ],
            3 => [
                'label' => '蜀',
                'peilv' => [
                    1 => ['id' => 1, 'name' => '赢', 'rate' => 35],
                    2 => ['id' => 2, 'name' => '输', 'rate' => 65],
                    3 => ['id' => 3, 'name' => '平', 'rate' => 25],
                ],
            ],
        ]
    ];

    public function __construct() {
        $this->wechat = app('wechat');
    }

    /**
     * 获取用户个人信息
     *
     * @return [type] [description]
     */
    public function getUserInfo() {
        $id = $this->getLoginUser();
        DB::setFetchMode(\PDO::FETCH_ASSOC);
        $user = DB::table('user')->where('id', $id)->first();
        $user['XYB'] = UserCoinLog::totalXyb($user['id']) * 100;
        $this->echoJson(0, '', $user);
    }

    /**
     * 出拳接口
     *
     * @return [type] [description]
     */
    public function hand(Request $request) {

        //$robot_id = $request->input('rid');   // 当前对战的机器人ID
        $user_army = $request->input('hand');   // 1-矛，2-盾，3-弓
        $gold = $request->input('gold');        // 100 500 1000 5000
        $nation = $request->input('nation');    // 1-魏 2-吴 3-蜀

        // 检查请求参数
        if (empty($user_army) || empty($gold) || empty($nation)) {
            return $this->echoJson(1, '请求参数不合法');
        }

        // 检查请求参数
        $user_army = intval($user_army);
        $nation = intval($nation);
        if (!in_array($user_army, [1,2,3], true) && !in_array($nation, [1, 2, 3], true)) {
            return $this->echoJson(1, '请求参数不合法');
        }
        $nation_label = $this->config['nation_types'][$nation]['label'];
        $user_army_label = $this->config['army_types'][$user_army];

        // 检查投注数量
        $gold = intval($gold)/100;
        if ($gold < 1) {
            return $this->echoJson(1, '投注数量不合法');
        }

        // 每次只能投足50
        if($gold > 50) {
            return $this->echoJson(1, '每次最多只能出5000兵哦');
        }

        // 限定操作频次
        $id = $this->getLoginUser();
        $redis = $this->getRedis();
        $key = "hlgc:hand:$id";
        if (!$redis->set($key, 'Y', Array('nx', 'px' => 1000))) {
            $this->echoJson(1, '您的操作过于频繁，请稍后再试');
        }

        // 真实用户
        DB::setFetchMode(\PDO::FETCH_ASSOC);
        $user = DB::table('user')->where('id', $id)->first();
        $uid = $user['id'];
        $user['XYB'] = UserCoinLog::totalXyb($uid);

        // 机器人
        $robot = DB::table('robot')->first();
        $rid = $robot['robot_id'];

        // 按配置概率判定胜负
        $peilv = $this->config['nation_types'][$nation]['peilv'];
        $result = $this->get_rand($peilv);

        // 根据当日盈亏调整概率，亏损超过阀值，则直接判定用户输
        $day_stat_key = sprintf("hlgc:stat:%s", date('Ymd', time()));
        $profit = $redis->get($day_stat_key);
        if (intval($profit) < self::threshold_xyb) {
            $result = 2;
        }

        // 判断用户小妖币是否不足
        if ($user['XYB'] < $gold) {
            return $this->echoJson(1, '您的小妖币余额不足！');
        }

        //用户玩游戏状态更新
        DB::table('user')->where('id', $id)->update(['status' => DB::raw('status|4')]);


        $insert_id = 0;
        switch ($result) {
            case 1:     // 用户赢
                $user_xyb   = $user['XYB'] + $gold;
                $robot_xyb  = 0;

                // 机器人出战兵种
                $robot_army = abs($user_army % 3) + 1;
                $robot_army_label = $this->config['army_types'][$robot_army];

                // 记录对局结果
                $data = [
                    'nation' => $nation,
                    'nation_label' => $nation_label,
                    'user_id' => $uid,
                    'robot_id' => $rid,
                    'bet_result' => $result,
                    'bet_xyb' => $gold,
                    'get_xyb' => $gold * 2,
                    'user_left_xyb' => $user_xyb,
                    'robot_left_xyb' => $robot_xyb,
                    'user_army' => $user_army,
                    'user_army_label' => $user_army_label,
                    'robot_army' => $robot_army,
                    'robot_army_label' => $robot_army_label,
                ];
                $insert_id = DB::table('game_hlgc_record_log')->insertGetId($data);

                // 更新用户小妖币
                $this->updateUserXYB($uid, -$gold);     // 消耗
                $this->updateUserXYB($uid, $gold * 2);  // 赢得

                // 当日盈亏统计
                $this->statDayProfitAndLoss(-$gold);

                // 奖励上级
                $this->rewardFinder($user, $gold);
                break;
            case 2:     // 用户输
                $user_xyb   = $user['XYB'] - $gold;
                $robot_xyb  = 0;

                // 判断余额
                if ($user_xyb < 0) {
                    return $this->echoJson(1, '您的小妖币余额不足！');
                }

                // 机器人出战兵种
                $robot_army = $user_army + 2 > 3 ? $user_army - 1 : $user_army + 2;
                $robot_army_label = $this->config['army_types'][$robot_army];

                // 记录对局结果
                $data = [
                    'nation' => $nation,
                    'nation_label' => $nation_label,
                    'user_id' => $uid,
                    'robot_id' => $rid,
                    'bet_result' => $result,
                    'bet_xyb' => $gold,
                    'get_xyb' => 0,
                    'user_left_xyb' => $user_xyb,
                    'robot_left_xyb' => $robot_xyb,
                    'user_army' => $user_army,
                    'user_army_label' => $user_army_label,
                    'robot_army' => $robot_army,
                    'robot_army_label' => $robot_army_label,
                ];
                $insert_id = DB::table('game_hlgc_record_log')->insertGetId($data);

                // 更新用户小妖币
                $this->updateUserXYB($uid, -$gold);

                // 当日盈亏统计
                $this->statDayProfitAndLoss($gold);
                break;
            default:    // 平局
                $user_xyb   = $user['XYB'];
                $robot_xyb  = 0;

                // 机器人出战兵种
                $robot_army = $user_army;
                $robot_army_label = $this->config['army_types'][$robot_army];

                // 记录对局结果
                $data = [
                    'nation' => $nation,
                    'nation_label' => $nation_label,
                    'user_id' => $uid,
                    'robot_id' => $rid,
                    'bet_result' => $result,
                    'bet_xyb' => $gold,
                    'get_xyb' => 0,
                    'user_left_xyb' => $user_xyb,
                    'robot_left_xyb' => $robot_xyb,
                    'user_army' => $user_army,
                    'user_army_label' => $user_army_label,
                    'robot_army' => $robot_army,
                    'robot_army_label' => $robot_army_label,
                ];
                $insert_id = DB::table('game_hlgc_record_log')->insertGetId($data);

                // 更新用户小妖币
                //$this->updateUserXYB($uid, $gold);

                // 当日盈亏统计
                //$this->statDayProfitAndLoss($gold);
                break;
        }

        //取得当前用户是否出现财神到
        $user = new \App\Tools\User\User();
        $data['isCaiShen'] = $user->getUserIsCoupon($uid);
        $this->echoJson(0, '', $data);
    }

    /**
     * 更新用户小妖币
     *
     * @param  [type] $uid  [description]
     * @param  [type] $gold [description]
     * @return [type]       [description]
     */
    private function updateUserXYB($uid, $gold) {
        $key = sprintf("%s-%s-%s-%s", self::bussiness_id, $uid, $gold, time());
        $tips = $gold > 0 ? '欢乐攻城赢得小妖币' : '欢乐攻城消耗小妖币';
        UserCoinLog::log(self::bussiness_id, $uid, UserCoinLog::TYPE_XYB, $gold, $tips, $key);
    }

    /**
     * 统计当日盈亏（记录保留7天）
     *
     * @param  [type] $gold [description]
     * @return [type]       [description]
     */
    private function statDayProfitAndLoss($gold) {
        $redis = $this->getRedis();
        $day_stat_key = sprintf("hlgc:stat:%s", date('Ymd', time()));
        $redis->incrBy($day_stat_key, $gold);
        $redis->setTimeout($day_stat_key, 7*24*60*60);
    }

    /**
     * 对战记录
     * @return [type] [description]
     */
    public function record(Request $request) {
        $nation = $request->input('nation');
        if (empty($nation)) {
            return $this->echoJson(1, '请求参数不合法');
        }

        $uid = $this->getLoginUser();
        $data = DB::table('game_hlgc_record_log')
        ->where('nation', $nation)
        ->where('user_id', $uid)
        ->limit(100)
        ->orderBy('created_time', 'desc')
        ->get();
        return $this->echoJson(0, '', $data);
    }

    /**
     * 获取用户个人信息
     *
     * @return [type] [description]
     */
    public function change() {

        // 考虑机器人数据量不多，获取机器人总数
        $robot_count = DB::table('robot')->count();

        // 随机取出一个机器人
        $offset = rand(1, $robot_count) - 1;
        DB::setFetchMode(\PDO::FETCH_ASSOC);
        $robot = DB::table('robot')->offset($offset)->limit(1)->first();

        // 如果机器人小妖币低于阀值，则自动调整机器人小妖币数量
        if ($robot['XYB'] < 62) {
            $robot['XYB'] = rand(8000, 67000)/100;
            DB::table('robot')->where('robot_id', $rid)->update(['XYB' => $robot['XYB']]);
        }

        // 返回数据
        $data = [
            'rid' => $rid,
            'nickname' => $robot['nickname'],
            'avatar' => $robot['avatar'],
            'coin' => $robot['XYB'] * 100,
        ];

        $this->echoJson(0, '', $data);
    }

    /**
     * 欢乐攻城概率算法
     *
     * @param  [type] $rand [description]
     * @return [type]       [description]
     */
    private function get_rand($rand) {
        $result = '';
        //概率数组的总概率精度
        $sum = 0;
        foreach ($rand as $v) {
            $sum += $v['rate'] * 100;
        }
        //概率数组循环
        foreach ($rand as $v) {
            $rate = $v['rate'] * 100;
            //抽取随机数
            $rand_num = mt_rand(1, $sum);
            if ($rand_num <= $rate) {
                //得出结果
                $result = $v['id'];
                break;
            } else {
                $sum -= $rate;
            }
        }
        unset ($rand);
        return $result;
    }

    /**
     * 验证登录
     *
     * @return [type] [description]
     */
    private function getLoginUser() {
        // 检查用户登录态
        $user = auth()->user();
        $uid = $user->id;
        return $uid;
    }

    /**
     * 获取Redis实例
     *
     * @return [type] [description]
     */
    private function getRedis() {
        static $redis = null;
        if (empty($redis)) {
            $redis = new \Redis();
            $redis->connect(env('REDIS_HOST'), env('REDIS_PORT'));
            $redis->auth(env('REDIS_PASSWORD'));
        }
        return $redis;
    }

    /**
     * 响应JSON/JSONP格式数据
     *
     * @param  integer $code [返回代码：0 成功 1 失败]
     * @param  string  $msg  [错误信息]
     * @param  array   $data [返回数据]
     * @return [type]        [description]
     */
    private function echoJson($code = 0, $msg = '', $data = []) {
        header('Content-type: application/json');
        $result = [
            'code'  => $code,
            'msg'   => $msg,
            'data'  => $data,
        ];
        $json = json_encode($result);

        // JSONP
        if (!empty($_GET['callback'])) {
            $json = $_GET['callback'] . "(" . $json . ")";
        }
        echo $json;
        exit(0);
    }

    /**
     * 奖励上级
     */
    public function rewardFinder($user, $total) {
        if ($this->reward_count) {
            if ($finder = User::where('id', $user['finder_id'])->first()) {
                if (floatval($xyb = bcmul($total, 0.01, 2))) {
                    if(!$gameZghpt = $finder->game_zghpt){
                        $gameZghpt = new GameZghpt();
                        $gameZghpt->user_id = $finder->id;
                        $gameZghpt->quota = 0;
                        $gameZghpt->level = 0;
                        $gameZghpt->save();
                    }
                    if($gameZghpt->level) {
                        $tmp_xyb = $xyb * 100;
                        $message = '恭喜您获得' . $tmp_xyb . '个小妖币的推荐奖励。';

                        $key = '6-'. $finder->id . '-' . $xyb . '-' . time() . '-1';
                        UserCoinLog::log( 6, $finder->id, UserCoinLog::TYPE_XYB, $xyb, '推荐奖励', $key );
                    } else {
                        $message = '您好，您错过了'. $xyb .'小妖币的红包，请<a href="http://ga.cloudxt.cn/zghpt/vip/page">立即升级VIP</a>！';
                    }

                    $this->dispatch(new SendWechatMessage($finder->openid, $message));

                    $this->reward_count--;
                    $this->rewardFinder($finder, $total);
                }
            }
        }
    }

}
